package com.loyal.dialog;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;

import com.loyal.R;
import com.loyal.helper.DialogHelper;

public class LoadingDialog extends AlertDialog {
    private ProgressBar mProgress;
    private TextView mMessageView;

    private Drawable mProgressDrawable;
    private Drawable mIndeterminateDrawable;
    private CharSequence mMessage;
    private boolean mIndeterminate;
    private boolean fullScreen;

    /**
     * Creates a Progress dialog.
     *
     * @param context the parent context
     */
    public LoadingDialog(@NonNull Context context) {
        super(context);
    }

    /**
     * Creates a Progress dialog.
     *
     * @param context    the parent context
     * @param themeResId the resource ID of the theme against which to inflate
     *                   this dialog, or {@code 0} to use the parent
     *                   {@code context}'s default alert dialog theme
     */
    public LoadingDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
    }

    protected LoadingDialog(@NonNull Context context, boolean cancelable, @Nullable @org.jetbrains.annotations.Nullable OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    /**
     * Creates and shows a ProgressDialog.
     *
     * @param context the parent context
     * @param title   the title text for the dialog's window
     * @param message the text to be displayed in the dialog
     * @return the ProgressDialog
     */
    public static LoadingDialog show(Context context, CharSequence title, CharSequence message) {
        return show(context, title, message, false);
    }

    /**
     * Creates and shows a ProgressDialog.
     *
     * @param context       the parent context
     * @param title         the title text for the dialog's window
     * @param message       the text to be displayed in the dialog
     * @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
     *                      indeterminate}, false otherwise
     * @return the ProgressDialog
     */
    public static LoadingDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate) {
        return show(context, title, message, indeterminate, false, null);
    }

    /**
     * Creates and shows a LoadingDialog.
     *
     * @param context       the parent context
     * @param title         the title text for the dialog's window
     * @param message       the text to be displayed in the dialog
     * @param indeterminate true if the dialog should be {@link #setIndeterminate(boolean)
     *                      indeterminate}, false otherwise
     * @param cancelable    true if the dialog is {@link #setCancelable(boolean) cancelable},
     *                      false otherwise
     * @return the LoadingDialog
     */
    public static LoadingDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable) {
        return show(context, title, message, indeterminate, cancelable, null);
    }

    /**
     * Creates and shows a LoadingDialog.
     *
     * @param context        the parent context
     * @param title          the title text for the dialog's window
     * @param message        the text to be displayed in the dialog
     * @param indeterminate  true if the dialog should be {@link #setIndeterminate(boolean)
     *                       indeterminate}, false otherwise
     * @param cancelable     true if the dialog is {@link #setCancelable(boolean) cancelable},
     *                       false otherwise
     * @param cancelListener the {@link #setOnCancelListener(OnCancelListener) listener}
     *                       to be invoked when the dialog is canceled
     * @return the LoadingDialog
     */
    public static LoadingDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable, OnCancelListener cancelListener) {
        LoadingDialog dialog = new LoadingDialog(context);
        dialog.setTitle(title);
        dialog.setMessage(message);
        dialog.setIndeterminate(indeterminate);
        dialog.setCancelable(cancelable);
        dialog.setOnCancelListener(cancelListener);
        dialog.show();
        return dialog;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Context mContext = getContext();
        LayoutInflater inflater = LayoutInflater.from(mContext);
        TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
        View view = inflater.inflate(R.layout.dialog_loading, null);
        mProgress = view.findViewById(android.R.id.progress);
        mMessageView = view.findViewById(R.id.message);
        setView(view);
        a.recycle();

        if (mProgressDrawable != null) {
            setProgressDrawable(mProgressDrawable);
        }
        if (mIndeterminateDrawable != null) {
            setIndeterminateDrawable(mIndeterminateDrawable);
        }
        if (mMessage != null) {
            setMessage(mMessage);
        }
        setIndeterminate(mIndeterminate);
        super.onCreate(savedInstanceState);
    }

    /**
     * Sets the drawable to be used to display the progress value.
     *
     * @param d the drawable to be used
     * @see ProgressBar#setProgressDrawable(Drawable)
     */
    public void setProgressDrawable(Drawable d) {
        if (mProgress != null) {
            mProgress.setProgressDrawable(d);
        } else {
            mProgressDrawable = d;
        }
    }

    /**
     * Sets the drawable to be used to display the indeterminate progress value.
     *
     * @param d the drawable to be used
     * @see ProgressBar#setProgressDrawable(Drawable)
     * @see #setIndeterminate(boolean)
     */
    public void setIndeterminateDrawable(Drawable d) {
        if (mProgress != null) {
            mProgress.setIndeterminateDrawable(d);
        } else {
            mIndeterminateDrawable = d;
        }
    }

    /**
     * Change the indeterminate mode for this LoadingDialog. In indeterminate
     * mode, the progress is ignored and the dialog shows an infinite
     * animation instead.
     * <p>
     * is always indeterminate and will ignore this setting.</p>
     *
     * @param indeterminate true to enable indeterminate mode, false otherwise
     */
    public void setIndeterminate(boolean indeterminate) {
        if (mProgress != null) {
            mProgress.setIndeterminate(indeterminate);
        } else {
            mIndeterminate = indeterminate;
        }
    }

    public void setFullScreen(boolean fullScreen) {
        this.fullScreen = fullScreen;
    }

    /**
     * Whether this LoadingDialog is in indeterminate mode.
     *
     * @return true if the dialog is in indeterminate mode, false otherwise
     */
    public boolean isIndeterminate() {
        if (mProgress != null) {
            return mProgress.isIndeterminate();
        }
        return mIndeterminate;
    }

    @Override
    public void setMessage(CharSequence message) {
        if (mProgress != null) {
            mMessageView.setText(message);
        } else {
            mMessage = message;
        }
    }

    @Override
    public void show() {
        Window window = getWindow();
        if (null != window)
            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
        super.show();
        DialogHelper.showFullScreen(window, fullScreen);
        DialogHelper.showPositionCenter(window);
    }
}
